import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import RGL, { WidthProvider } from 'react-grid-layout';
import shortid from 'shortid';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import { ReactSortable } from 'react-sortablejs';
import { Col, Row, Button, Space, Menu, message } from 'antd';
import MenuHover from './components/MenuHover';
import DataModel from './components/DataModel';
import FilterModal from './components/FilterModal';
import DataFormat from './components/DataFormat';
import DropMenu from './components/DropMenu';

import Sort from './components/Sort';

import { BarChartOutlined, TableOutlined, FilterOutlined, PieChartOutlined, LineChartOutlined } from '@ant-design/icons';
import user from './user.png';
import modelData from './MockData/component.js';

const ReactGridLayout = WidthProvider(RGL);
const { SubMenu } = Menu;
const GridLayoutItem = React.forwardRef((props: { i: string; onRemove: (i: string) => void; value: string }, ref) => {
  const [height, setHeight] = useState(300);
  const [width, setWidth] = useState(300);
  const divRef = useRef<any>();

  function calcHeightAndWidth() {
    if (divRef && divRef.current) {
      setHeight(divRef.current.getBoundingClientRect().height);
      setWidth(divRef.current.getBoundingClientRect().width);
    }
  }

  useImperativeHandle(ref, () => {
    return {
      calcHeightAndWidth,
    };
  });

  useEffect(() => {
    calcHeightAndWidth();
  }, []);

  return (
    <div
      ref={divRef}
      style={{ backgroundColor: '#ddd', height: '100%' }}
      onDoubleClick={() => {
        props.onRemove(props.i);
      }}
    >
      {/* {height} {width}
      <p>{props.value}</p> */}
      <ReactGridLayout
        style={{ minHeight: 300 }}
        cols={24}
        rowHeight={20}
        droppingItem={{ i: 'dropping', w: 5, h: 2 }}
        resizeHandles={['sw', 'nw', 'se', 'ne']}
        onDrop={console.log}
      />
    </div>
  );
});

interface ItemType {
  column: string;
  id: number;
  label: string;
}

const SortableList: React.FC = props => {
  const [state, setState] = useState<ItemType[]>([]);

  console.log('state', state);

  function onAdd(evt: any) {
    const newIndex = evt.newIndex;
    const item = JSON.parse(evt.clone.dataset.item);
    const arr = [...state];

    if (!state.map(t => t.id).includes(item.id)) {
      arr.splice(newIndex, 0, item);
      setState([...arr]);
    } else {
      message.warn('重复');
    }
  }

  function onUpdate(evt: any) {
    const oldIndex = evt.oldIndex;
    const newIndex = evt.newIndex;
    const arr = [...state];
    arr.splice(newIndex, 0, ...arr.splice(oldIndex, 1));
    setState([...arr]);
  }

  const menu = (
    <Menu>
      <Menu.ItemGroup title="Group title">
        <Menu.Item>1st menu item</Menu.Item>
        <Menu.Item>2nd menu item</Menu.Item>
      </Menu.ItemGroup>
      <SubMenu title="sub menu">
        <Menu.Item>3rd menu item</Menu.Item>
        <Menu.Item>4th menu item</Menu.Item>
      </SubMenu>
    </Menu>
  );

  return (
    <DropMenu menu={menu}>
      <ReactSortable
        list={state}
        style={{
          width: 200,
          height: 200,
          border: '1px solid #999',
        }}
        setList={list => {
          console.log('setList', list);
        }}
        className="sortableList"
        group={{ name: 'shared', pull: 'clone' }}
        onAdd={onAdd}
        onUpdate={onUpdate}
      >
        {state.map(item => (
          <div key={item.column} style={{ padding: 10, cursor: 'pointer' }} onClick={e => console.log(e)}>
            {item.label}
          </div>
        ))}
      </ReactSortable>
    </DropMenu>
  );
};

const GridLayout = () => {
  const [layout, setLayout] = useState<RGL.Layout[]>();
  const [dropping, setDropping] = useState(false);

  const layoutItemRef = useRef<any>({});

  function onLayoutChange(layout: RGL.Layout[]) {
    if (dropping) return;

    setLayout(layout.filter(t => t.i !== 'dropping'));

    Object.keys(layoutItemRef.current).forEach(t => {
      layoutItemRef.current[t]?.calcHeightAndWidth();
    });
  }

  function onRemove(i: string) {
    setLayout(layout ? layout?.filter(t => t.i !== i) : []);
  }

  function onDrop(newlayout: RGL.Layout[], item: RGL.Layout, e: any) {
    console.log('onDrop:e', e.dataTransfer.getData('vizType'));
    setDropping(false);
    setLayout(
      newlayout.map(t => ({
        ...t,
        i:
          t.i === 'dropping'
            ? `${shortid.generate()}${e.dataTransfer.getData('vizType')}` //拼接
            : t.i,
      }))
    );
  }

  const options = [
    {
      label: '图表',
      value: 'cahrt',
      icon: <BarChartOutlined />,
      children: [
        {
          label: '饼状图',
          value: '饼状图',
          icon: <PieChartOutlined />,
        },
        {
          label: '折线图',
          value: '折线图',
          icon: <LineChartOutlined />,
        },
      ],
    },
    {
      label: '表格',
      value: 'table',
      icon: <TableOutlined />,
      children: [
        {
          label: '表格1',
          value: '表格1',
          icon: <TableOutlined />,
        },
        {
          label: '表格2',
          value: '表格2',
          icon: <TableOutlined />,
        },
      ],
    },
    {
      label: '筛选器',
      value: 'filter',
      icon: <FilterOutlined />,
      children: [
        {
          label: '筛选器1',
          value: '筛选器1',
          icon: <img src={user} />,
        },
        {
          label: '筛选器2',
          value: '筛选器2',
          icon: <FilterOutlined />,
        },
      ],
    },
  ];

  function onTablesourceChange(id: number) {
    return Promise.resolve(id % 2 ? modelData.catSource : modelData.catSource1);
  }

  const [filterModalModalVisble, setFilterModalModalVisble] = useState(false);
  const [dataFormatModalVisble, setDataFormatModalVisble] = useState(false);
  const [sortModalVisble, setSortModalVisble] = useState(false);

  return (
    <div>
      <div
        style={{
          backgroundColor: '#f6f6f6',
        }}
      >
        <MenuHover options={options} onDragStartCallback={() => setDropping(true)} />
        <Space>
          <Button type="primary" onClick={() => setFilterModalModalVisble(true)}>
            过滤
          </Button>
          <Button type="primary" onClick={() => setDataFormatModalVisble(true)}>
            格式化
          </Button>
          <Button type="primary" onClick={() => setSortModalVisble(true)}>
            排序
          </Button>
        </Space>
      </div>
      <Sort
        isModalVisible={sortModalVisble}
        handleCancel={() => setSortModalVisble(false)}
        handleOk={e => {
          // setSortModalVisble(false);
          console.log('e: ', e);
        }}
        params="asc"
      />
      <DataFormat
        params={{
          decimal: 3, //小数位
          unit: 'none', //单位
          thousandSign: true, //千位符
          percentDecimal: 2, //百分比小数位
          date: 'none', //时间
        }}
        isModalVisible={dataFormatModalVisble}
        handleCancel={() => setDataFormatModalVisble(false)}
        handleOk={e => {
          // setDataFormatModalVisble(false);
          console.log('e: ', e);
        }}
      />

      <FilterModal
        params={{
          type: 'simple',
          data_type: 'string',
          col: 'desc',
          clause: 'where',
        }}
        isModalVisible={filterModalModalVisble}
        handleCancel={() => setFilterModalModalVisble(false)}
        handleOk={e => {
          setFilterModalModalVisble(false);
          console.log('e: ', e);
        }}
      />

      <Row gutter={24}>
        <Col span={4}>
          <DataModel tableSource={modelData?.sourceData} onTablesourceChange={onTablesourceChange} width={250} />
        </Col>

        <Col span={12} style={{ backgroundColor: '#ececec' }}>
          <div>
            <SortableList />
          </div>
          <ReactGridLayout
            style={{ minHeight: 300 }}
            cols={24}
            rowHeight={20}
            isDroppable={dropping}
            droppingItem={{ i: 'dropping', w: 5, h: 2 }}
            resizeHandles={['sw', 'nw', 'se', 'ne']}
            layout={layout}
            // allowOverlap
            onLayoutChange={onLayoutChange}
            onDrop={onDrop}
            // onDropDragOver={onDropDragOver}
          >
            {layout?.map(t => (
              <div key={t.i}>
                {
                  <GridLayoutItem
                    ref={item => {
                      layoutItemRef.current[t.i] = item;
                    }}
                    i={t.i}
                    onRemove={onRemove}
                    value={t.i.substr(9)}
                  />
                }
              </div>
            ))}
          </ReactGridLayout>
        </Col>
      </Row>
    </div>
  );
};

export default GridLayout;
